﻿// ## 2023/12/01 # 黑店小小二 # 修复攻占小城后已分封封地被清空 
// ## 2023/05/18 # 铃 # !!to 风神.有时候会出现府兵武将存在的情况,会有府兵病死之类的bug出现.需要修复
// ## 2023/05/06 # 铃 # 由于修改了分封条件,所以会出现很多文官将领.因此,府兵武将统率+武力较差的时候,(或者当兵力过少的时),强制出弩兵.并且统率的最小适性提高到B.
// ## 2023/05/06 # 铃 # 府兵出征的时候,弩兵会站在两格距离(避免出生在一格以内而近战攻击)
// ## 2023/05/03 # 铃 # 降低府的门槛之后,满足不了3000的出兵要求,因此AI的分封还是变成3000.(同时测试一下让府兵低于3000但是大于1000也能出征会怎么样.出征下限临时改为1000)
// ## 2023/05/02 # 铃 # 为了扩大府的游戏价值,降低了府分配的门槛,金和兵的门槛从3000→1500,统率80→属性80.
//  ## 2023/03/18 # 铃 # 重做了府的信息显示外观,添加了府的人口和内政收支系统.将军的属性会影响府的收支.(相对城市来说,府的行政等级是县.)
//  ## 2023/03/15 # 铃 # 由于新增了AI优先攻击府的逻辑,会导致部队在府附近缠打,经过反复测试,为了提高府的战略价值.减少了府兵攻击力(府武将属性85→75)的同时,增加府的耐久SPEC_HP_BONUS从500→800, ##
//  ## 2023/03/09 # 铃 # 有时候府的信息会往下掉的问题(行数递增迭代的玄学错误,把信息行数变量替换为常量@江东新风 ##
//  ## 2023/03/08 # 铃 # 参考大浪MOD的修改建议,巡防范围从6格降低为5格.府兵平均能力值降低到75左右 ##
//  ## 2023/03/08 # 铃 # 为了平衡现在版本的士兵数量和收支水平,府兵上限降低到15000,每旬度增加的兵力从RAND(200,400)降低到RAND(20,100),(单个府一年增4000兵力左右),也略微降低钱粮收支.##
//  ## 2023/03/08 # 江东新风 # 用府兵移动动画替换移动命令,修复移动的时候府兵二次攻击的BUG##

// ## 2022/03/26 # 江东新风 # 府兵部队生成失败bug ##
// ## 2022/03/21 # 江东新风 # 府兵部队身份异常bug,封地耐久稍提升 ##
// ## 2022/03/20 # 江东新风 # 修复武将所属变更后无法再分封bug ##
// ## 2022/03/18 # 江东新风 # 分封选武将取消闪退bug ##
// ## 2022/03/16 # 江东新风 # 分封及解除分封取消闪退bug ##
// ## 2022/02/14 # 江东新风 # 部分常量中文化 ##
// ## 2021/02/06 # 江东新风 # 府兵带兵数调整为被封武将官职低一级的带兵数##
// ## 2021/01/29 # 江东新风 # 府兵不进攻问题，武将所属变更封地未同步问题，稍微削弱府兵属性##
// ## 2021/01/11 # 江东新风 # 重复分封问题 ##
// ## 2021/01/05 # 江东新风 # 修复前线封地势力bug，玩家运输部队可补给封地 ##
// ## 2021/12/02 # 江东新风 # ai分封和解除分封 ##
// ## 2021/10/29 # 江东新风 # 结构体存储调用方式改进 ##
// ## 2021/10/24 # 江东新风 # 将pk::add_troops换成ch::add_troops以修正显示错误 ##
// ## 2021/10/10 # 江东新风 # 初始制作 ##


/*
待处理：玩家府兵资源的输送，建筑被破坏时，封地信息清空
*/

namespace 府兵系统
{
	// ================ CUSTOMIZE ================

	const int ACTION_COST = 20;	 // 行动力消耗
	const int GOLD_COST = 500;	 // 金消耗
	const int FOOD_COST = 3000;	 // 粮消耗
	const int TROOP_COST = 2000; // 兵消耗
	const int SPEC_HP_BONUS = 1000;

	const int 府兵巡防范围 = 5; // 默认6，范围3-10

	int 地名_id = -1;

	const bool 调试模式 = false;
	class Main
	{
		pk::building @building_;
		pk::building @loc_building;
		pk::force @force_;
		pk::person @kunshu_;
		pk::person @actor;
		pk::city @city_;
		pk::unit @src_unit_;
		pk::point src_pos_;
		bool has_moved_ = false;

		string spec_name;
		int check_result_;
		pk::list<pk::building @> able_spec_;
		pk::list<pk::person @> able_person_;

		// array<array<int>> base_info(15, array<int>(5, -1));//最多一个势力存15据点，存（据点id，据点状态（前线，警戒），玩家部队数，敌势力部队数，5格内是否有敌部队）
		Main()
		{
			pk::bind(112, pk::trigger112_t(onTurnEnd));
			pk::bind(107, pk::trigger107_t(onNewDay_domestic));
			pk::bind(202, pk::trigger202_t(onAIRunningOrder));
			pk::bind(152, pk::trigger152_t(onPersonForceChange));
			pk::bind(166, pk::trigger166_t(onBuildingForceChange));
			pk::bind2(164, pk::trigger164_t(afterkillbuilding), 999);
			pk::set_func(63, pk::func63_t(GetBuildingHp));
			add_menu();
			add_unit_menu();
		}

		void add_menu()
		{
			pk::menu_item item;
			item.menu = 101;
			// item.pos = 3;
			item.shortcut = "";
			item.init = pk::building_menu_item_init_t(init);
			item.is_visible = pk::menu_item_is_visible_t(isVisible);
			item.is_enabled = pk::menu_item_is_enabled_t(isEnabled);
			item.get_text = pk::menu_item_get_text_t(getText);
			item.get_desc = pk::menu_item_get_desc_t(getDesc);
			item.handler = pk::menu_item_handler_t(handler);
			pk::add_menu_item(item);

			pk::menu_item menu_item_领地_县城管理;
			menu_item_领地_县城管理.menu = 0;
			menu_item_领地_县城管理.pos = 0;
			// menu_item_领地_县城管理.shortcut = shortcut_领地_县城管理;
			menu_item_领地_县城管理.init = pk::building_menu_item_init_t(init_领地_县城管理);
			menu_item_领地_县城管理.is_visible = pk::menu_item_is_visible_t(isVisible_领地_县城管理);
			menu_item_领地_县城管理.is_enabled = pk::menu_item_is_enabled_t(isEnabled_领地_县城管理);
			menu_item_领地_县城管理.get_text = pk::menu_item_get_text_t(getText_领地_县城管理);
			menu_item_领地_县城管理.get_desc = pk::menu_item_get_desc_t(getDesc_领地_县城管理);
			menu_item_领地_县城管理.handler = pk::menu_item_handler_t(handler_领地_县城管理);
			pk::add_menu_item(menu_item_领地_县城管理);

			pk::menu_item menu_item_领地_解除县城管理;
			menu_item_领地_解除县城管理.menu = 0;
			menu_item_领地_解除县城管理.pos = 0;
			// menu_item_领地_解除县城管理.shortcut = shortcut_领地_解除县城管理;
			menu_item_领地_解除县城管理.init = pk::building_menu_item_init_t(init_领地_解除县城管理);
			menu_item_领地_解除县城管理.is_visible = pk::menu_item_is_visible_t(isVisible_领地_解除县城管理);
			menu_item_领地_解除县城管理.is_enabled = pk::menu_item_is_enabled_t(isEnabled_领地_解除县城管理);
			menu_item_领地_解除县城管理.get_text = pk::menu_item_get_text_t(getText_领地_解除县城管理);
			menu_item_领地_解除县城管理.get_desc = pk::menu_item_get_desc_t(getDesc_领地_解除县城管理);
			menu_item_领地_解除县城管理.handler = pk::menu_item_handler_t(handler_领地_解除县城管理);
			pk::add_menu_item(menu_item_领地_解除县城管理);
		}

		void add_unit_menu()
		{
			pk::menu_item item;
			item.menu = 1;
			// item.pos = 3;
			item.shortcut = "";
			item.init = cast<pk::unit_menu_item_init_t @>(function(unit, src_pos) { @main.src_unit_ = @unit; main.src_pos_ = src_pos; });
			item.is_visible = cast<pk::menu_item_is_visible_t @>(function() { return (main.src_unit_).type == 部队类型_运输; });
			item.is_enabled = cast<pk::menu_item_is_enabled_t @>(function() { if (main.src_unit_.get_pos() != pk::get_unit_menu_hex_pos()) main.has_moved_ = true; return true;/* main.isEnabled(지원항목_금);*/ });
			item.get_text = cast<pk::menu_item_get_text_t @>(function() { return pk::encode("县城补给"); });
			item.get_desc = cast<pk::menu_item_get_desc_t @>(function() { return pk::encode("向相邻的\x1b[1x县城\x1b[0x按1:2比例支援兵力兵粮."); });
			item.get_targets = cast<pk::unit_menu_item_get_targets_t @>(function() { return main.get_targets(1); });
			item.handler = cast<pk::unit_menu_item_handler_t @>(function(dst_pos) { return main.unit_handler(dst_pos); });
			// item.handler = pk::menu_item_handler_t(handler);
			pk::add_menu_item(item);
		}

		// 为府兵建筑增加耐久
		int GetBuildingHp(pk::building @building, pk::facility @facility)
		{
			int facility_id = facility.get_id();
			int max_hp = facility.hp;
			if (facility_id >= 设施_阵 and facility_id <= 设施_连弩楼)
			{
				int spec_id = ch::get_spec_id(building);
				// pk::trace(pk::format("一次building_id：{},building_name:{},facility.hp:{},spec_id:{},ch::get_spec_p(spec_id).person:{},max_hp:{}", building.get_id(), pk::decode(pk::get_name(building)), facility.hp, spec_id, ch::get_spec_p(spec_id).person, max_hp));

				if (spec_id != -1)
				{

					// max_hp += SPEC_HP_BONUS;
					max_hp += 800;

					// pk::trace(pk::format("二次building_id：{},building_name:{},facility.hp:{},spec_id:{},ch::get_spec_p(spec_id).person:{},max_hp:{}", building.get_id(), pk::decode(pk::get_name(building)), facility.hp, spec_id, ch::get_spec_p(spec_id).person, max_hp));
					auto spec_t = ch::get_spec_p(spec_id);
					if (pk::is_valid_person_id(spec_t.person))
					{
						max_hp += SPEC_HP_BONUS;
						if (spec_t.get_spec_set(SPEC_MAX_INC))max_hp += 5000;
						//if (spec_id >= ch::get_normal_spec_end())max_hp += 5000;
						// pk::trace(pk::format("三次building_id：{},building_name:{},facility.hp:{},spec_id:{},ch::get_spec_p(spec_id).person:{},max_hp:{}", building.get_id(), pk::decode(pk::get_name(building)), facility.hp, spec_id, ch::get_spec_p(spec_id).person, max_hp));
					}
				}
			}
			return max_hp;
		}

		void afterkillbuilding(/*pk::unit@ attacker,*/ int force_id, int facility_id, const pk::point& in pos, int pre_building_id)
		{
			ch::特殊地名争夺处理(facility_id, force_id, pos, pre_building_id);
		}

		// 府内政和收支
		void onNewDay_domestic()
		{
			if (pk::get_day() == 1) // 每月
			{
				// 金收入
				for (int i = 0; i < 据点_末; ++i)
				{
					for (int j = 0; j < 最大城市县城数; ++j)
					{
						int spec_id = ch::get_base_spec(i, j);
						pk::building @building = pk::get_building(ch::to_building_id(spec_id));



						int check_result = spec_status_check(spec_id, building);
						//pk::trace(pk::format("1地名：{},i：{},check_result:{}", ch::get_spec_name(i), i, check_result));

						if (check_result == 0)
							continue;
						auto spec_t = ch::get_spec_p(spec_id);

						// 府附近无敌兵时,自然增长每个月200耐久
						if (check_result == 1 and building.hp - pk::get_max_hp(building) < 0)
							building.hp += 200;

						// 有将领时每月恢复300耐久
						if (check_result == 2 and building.hp - pk::get_max_hp(building) < 0)
							building.hp += 300;

						building.hp = pk::min(pk::get_max_hp(building), building.hp);

						//pk::trace(pk::format("2地名：{},i：{},check_result:{}", ch::get_spec_name(i), i, check_result));

						if (check_result == 2)
						{
							int gold_income = inter::cal_spec_gold_income(spec_id, 0);

							int gold_dif = spec_t.add_gold(gold_income); // spec_t.gold += gold_income;
							pk::combat_text(gold_dif, 3, ch::get_spec_pos(spec_id));

							// 粮处理
							if (pk::is_first_month_of_quarter(pk::get_month()))
							{
								int food_income = inter::cal_spec_food_income(spec_id, 0);

								spec_t.add_food(food_income);

								pk::combat_text(food_income, 4, ch::get_spec_pos(spec_id));
							}

							// 耗粮处理
							int troops_dif = 0;
							int food_dif = 0;

							// 府兵消耗粮草,月度=旬度*3
							if (pk::enemies_around(building))
								food_dif = spec_t.troops / 1000 * UNIT_FOOD_USE::基础耗粮 * 3;
							else
								food_dif = spec_t.troops / 1000 * BUILDING_FOOD_USE::基础耗粮 * 3;

							if (spec_id >= ch::get_normal_spec_end()) food_dif /= 10;

							// 士兵逃亡
							if (-food_dif + spec_t.food < 0)
							{
								troops_dif = int(spec_t.troops * 0.1 + 1000);
								spec_t.add_troops(-pk::min(troops_dif, spec_t.troops));
								if (building.is_player())
								{
									string t = pk::format("\x1b[1x{}\x1b[0x粮草不足,部分士兵逃亡.", ch::get_spec_name(spec_id));
									pk::message_box(pk::encode(pk::format(" \x1b[1x{}\x1b[0x的士兵由于军粮不足而逃亡了.", ch::get_spec_name(spec_id))));
									pk::history_log(building.pos, pk::get_force(building.get_force_id()).color, pk::encode(t));
								}
							}
							//	spec_t.troops = int(spec_t.troops * 0.9);
							spec_t.add_food(-food_dif); // spec_t.food += food_income;

							pk::combat_text(-food_dif, 4, ch::get_spec_pos(spec_id));

							// 人口和征兵处理

							pk::int_int data_gain = inter::cal_spec_pop_troops_income(spec_id);
							int pop_gain = data_gain.first;
							int troops_gain = data_gain.second;

							spec_t.add_population(pop_gain);
							spec_t.add_troops(troops_gain);
							pk::combat_text(troops_gain, 1, ch::get_spec_pos(spec_id));

						}
					}
				}
			}
		}

		int spec_status_check(int spec_id, pk::building @building)
		{

			if (!pk::is_alive(building))
				return 0;
			int force_id = building.get_force_id();
			// if (!pk::is_normal_force(force_id))
			// 	return 0;

			pk::force @force = pk::get_force(force_id);
			if (!pk::is_alive(force))
				return 0;

			if (pk::enemies_around(building))
				return 0;

			auto spec_t = ch::get_spec_p(spec_id);
			int person_id = spec_t.person;
			if (!pk::is_normal_person(person_id))
				return 1;
			pk::person @person = pk::get_person(person_id);
			if (!pk::is_alive(person))
				return 1;
			if (force_id != person.get_force_id())
				return 1;
			return 2;
		}

		// 府兵进攻及县城管理的地方
		void onTurnEnd(pk::force @force)
		{
			// for (int i = 0; i < ch::get_spec_end(); ++i)
			// {
			// 	pk::point pos = ch::get_spec_pos(i);
			// 	pk::building @building0 = pk::get_building(pos);
			// 	pk::hex @hex = pk::get_hex(pos);
			// 	pk::trace(pk::format("地名：{},i：{},地形:{}", ch::get_spec_name(i), i, hex.terrain));
			// }

			if (!pk::is_alive(force))
				return;

			// 府兵进攻
			for (int i = 0; i < ch::get_spec_end(); ++i)
			{
				pk::point pos = ch::get_spec_pos(i);
				pk::building @building0 = pk::get_building(pos);

				if (!pk::is_alive(building0))
					continue;
				//if (调试模式)
				//pk::trace("府兵 building id:" + building0.get_id());
				if (building0.get_force_id() != force.get_id())
					continue;
				auto spec_t = ch::get_spec_p(i);

				if (spec_t.person != -1)
				{
					int city_id = pk::get_building_id(building0.pos);
					auto base_t = ch::get_base_p(city_id);
					auto building_p = ch::get_baseIA(city_id);

					pk::point dst_pos = get_enemy_unit_pos(building0);
					if (调试模式)
						pk::trace("府兵进攻0 building id:" + building0.get_id() + ch::get_spec_name(building0.get_id() - 100) + "dst_pos:" + dst_pos.x + "," + dst_pos.y);
					if (pk::is_valid_pos(dst_pos))
					{
						if (调试模式)
							pk::trace("府兵进攻 building id:" + building0.get_id() + ch::get_spec_name(building0.get_id() - 100) + "dst_pos:" + dst_pos.x + "," + dst_pos.y);
						// 根据mod强度设置府兵出征部队数
						int extra = 0;
						if (i >= ch::get_normal_spec_end()) extra = 5;
						func_府兵部队_生成(building0, pk::get_person(spec_t.person), dst_pos, i, spec_t.troops, spec_t.gold, spec_t.food, pk::min(3, ch::get_set_p(0).spec_strength + 1 + extra));
					}
				}
			}
		}

		// 确保空城也能重设地名设施
		void onBuildingForceChange(pk::building @base, pk::force @force)
		{
			// pk::trace("确保空城也能重设地名设施1");
			if (特定地点特定设施可争夺)
			{
				if (base.get_force_id() == -1) /*and pk::is_normal_force(force)*/
				{
					int base_id = base.get_id();
					if (pk::is_valid_base_id(base_id))
					{
						// 需要遍历地名设施
						// pk::trace("确保空城也能重设地名设施");
						for (int i = 0; i < ch::get_normal_spec_end(); i++) // 注意，地名末和length不一定一致
						{
							pk::point pos0 = ch::get_spec_pos(i);
							pk::hex @hex = pk::get_hex(pos0);
							// pk::trace(ch::get_spec_name(i) + "area" + hex.area + "base_id" + base_id);
							if (hex.area == base_id) // 游戏中区域id和据点id一致
							{
								pk::building @spec = pk::get_building(pos0);
								int force_id = force.get_id();
								if (pk::is_valid_force_id(spec.init_force)) continue;//需要排除本有势力的据点
								if (pk::is_alive(spec) and spec.init_force != force_id)
								{
									spec.init_force = pk::is_valid_force_id(force_id)? force_id:-1;
									ch::reset_spec(i);
								}
								// pk::set_district(pk::get_building(pk::get_building_id(pos0)), pk::get_district(pk::get_district_id(force, 0)), /*占领*/0);
							}
						}
					}
				}
			}
		}

		void onPersonForceChange(pk::person @person, pk::force @force)
		{
			int person_id = person.get_id();
			int spec_id = ch::get_person_p(person_id).spec_id;
			if (spec_id >= 0)
			{
				ch::reset_spec(spec_id);
			}
		}

		void onAIRunningOrder(pk::ai_context @context, pk::building @building, int cmd)
		{
			if (cmd == 据点AI_县城管理)
			{
				if (pk::enemies_around(building))
					return;
				if (pk::get_troops(building) <= int(TROOP_COST * 2))
					return;
				else if (pk::get_food(building) <= int(FOOD_COST * 2))
					return;
				else if (pk::get_gold(building) <= int(GOLD_COST * 2))
					return;

				//pk::trace(pk::format("0,{}分封判定))", pk::decode(pk::get_name(building))));

				pk::list<pk::person @> able_person = get_able_person(pk::get_force(building.get_force_id()));
				pk::list<pk::building @> able_spec = get_city_able_spec_building(building);

				//pk::trace(pk::format("1,{}分封判定))", pk::decode(pk::get_name(building))));

				if (run_order_before(building, able_person, able_spec))
					run_order(building, able_person[0], ch::get_spec_id(able_spec[0]), false);
				else if (调试模式)
					pk::trace(pk::format("{}分封判定不满足))", pk::decode(pk::get_name(building))));
			}
			else if (cmd == 据点AI_解除县城管理)
			{
				pk::list<pk::person @> spec_person = get_base_spec_person(building);
				if (spec_person.count != 0)
				{
					run_order_解除县城管理(building, spec_person, false);
				}
			}
		}

		bool run_order_before(pk::building @building0, pk::list<pk::person @>& able_person, pk::list<pk::building @>& able_spec)
		{


			int check_result = check_avaliable(building0, able_person, able_spec);

			if (check_result != 0)
				return false;

			// 在此处选好目标
			pk::person @person0 = able_person[0];
			able_person.clear();
			able_person.add(person0);

			pk::building @building_spec = able_spec[0];
			able_spec.clear();
			able_spec.add(building_spec);

			return true;
		}

		bool run_order(pk::building @building0, pk::person @actor, int spec_id, bool is_player = true)
		{
			if (!ch::is_valid_spec_id(spec_id))
				return false;

			//pk::trace(pk::format("2,{}分封判定))", pk::decode(pk::get_name(building0))));

			auto spec_t = ch::get_spec_p(spec_id);
			if (pk::is_valid_person_id(spec_t.person))
			{
				ch::get_person_p(spec_t.person).spec_id = -1;
			} // 清空原来武将的对应记录
			int person_id = actor.get_id();
			if (pk::is_valid_person_id(person_id) and is_player) // 清空原将领信息
			{
				int actor_spec_id = ch::get_person_p(person_id).spec_id;
				if (ch::is_valid_spec_id(actor_spec_id))
				{
					ch::get_spec_p(actor_spec_id).person = -1;
				}
			}
			spec_t.person = person_id;
			spec_t.set_gold(is_player ? GOLD_COST : GOLD_COST);
			spec_t.set_food(is_player ? FOOD_COST : FOOD_COST);
			spec_t.set_troops(is_player ? TROOP_COST : TROOP_COST);
			auto spec_building = pk::get_building(spec_id + 100);
			spec_building.hp += SPEC_HP_BONUS;
			ch::get_person_p(person_id).spec_id = spec_id;
			// 计算行动力消耗
			auto district = pk::get_district(building0.get_district_id());
			pk::add_ap(district, -ACTION_COST);

			//pk::trace(pk::format("3,{}分封判定))", pk::decode(pk::get_name(building0))));

						// 计算金消耗
			pk::add_gold(building0, -GOLD_COST, true);
			pk::add_food(building0, -FOOD_COST, true);
			ch::add_troops(building0, -TROOP_COST, true);

			// 人物忠诚上升
			pk::add_loyalty(actor, 10);
			spec_name = ch::get_spec_name(spec_id);

			if (!is_player)
			{
				string t = pk::format("\x1b[2x{}\x1b[0x被任命管理\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(pk::get_person(person_id))), spec_name);
				pk::history_log(building0.pos, pk::get_force(building0.get_force_id()).color, pk::encode(t));
			}
			else
				pk::scene(pk::scene_t(scen_县城管理));
			return true;
		}

		bool run_order_解除县城管理(pk::building @building0, pk::list<pk::person @> spec_person, bool is_player = true)
		{
			for (int i = 0; i < spec_person.count; ++i)
			{
				int person_id = spec_person[0].get_id();
				int spec_id = ch::get_person_p(person_id).spec_id;
				if (!ch::is_valid_spec_id(spec_id))
					continue;
				ch::get_person_p(person_id).spec_id = -1;
				auto spec_t = ch::get_spec_p(spec_id);
				spec_t.person = -1;
				int gold = spec_t.gold;
				int food = spec_t.food;
				int troops = spec_t.troops;
				spec_t.set_gold(0);
				spec_t.set_food(0);
				spec_t.set_troops(0);
				pk::building @spec_building = pk::get_building(spec_id + 100);
				spec_building.hp = pk::max(spec_building.hp - SPEC_HP_BONUS, 0);

				pk::add_gold(building0, gold, false);
				pk::add_food(building0, food, false);
				pk::add_troops(building0, troops, false);

				spec_name = ch::get_spec_name(spec_id);
				if (!is_player)
				{
					string t = pk::format("\x1b[2x{}\x1b[0x被解除了\x1b[1x{}\x1b[0x的管理权", pk::decode(pk::get_name(pk::get_person(person_id))), spec_name);
					pk::history_log(building0.pos, pk::get_force(building0.get_force_id()).color, pk::encode(t));
				}
				else
				{
					pk::message_box(pk::encode("主公是不信任我了吗....."), spec_person[0]);
					//pk::add_loyalty(spec_person[0], -int(spec_person[0].loyalty * 0.5f));
				};
			}
			return true;
		}
		//========================================玩家县城管理=================================================================//

		void init(pk::building @building)
		{
			@building_ = @building;
			@force_ = pk::get_force(building_.get_force_id());

			@kunshu_ = pk::get_person(pk::get_kunshu_id(building));
			@city_ = pk::building_to_city(building);
			able_spec_ = get_able_building(building);
			able_person_ = get_able_person(force_);
			if (调试模式)
				pk::trace("able_spec_" + able_spec_.count + "able_person_" + able_person_.count);
			check_result_ = check_avaliable(building_, able_person_, able_spec_);
		}

		bool isVisible()
		{
			// if (building_.get_id() != kunshu_.service)
			// 	return false;
			return true;
		}

		bool isEnabled()
		{
			if (check_result_ != 0)
				return false;
			else
				return true;
		}

		string getDesc()
		{
			switch (check_result_)
			{
				case 1:
					return pk::encode("没有可用的武将. ");
				case 2:
					return pk::encode("没有可用县城.");
				case 3:
					return pk::encode(pk::format("行动力不足 (必须 {} 行动力)", ACTION_COST));
				case 4:
					return pk::encode(pk::format("兵力不足.(必须{} 兵力)", TROOP_COST));
				case 5:
					return pk::encode(pk::format("食物不足.(必须{} 兵粮)", FOOD_COST));
				case 6:
					return pk::encode(pk::format("资金不足 (必须 {} 资金)", GOLD_COST));
				case 8:
					return pk::encode("附近有敌军无法执行.");
				case 0:
					return pk::encode(pk::format("执行县城管理. (行动力 {}, 金 {}, 粮 {}, 兵 {})", ACTION_COST, GOLD_COST, FOOD_COST, TROOP_COST));
				default:
					return pk::encode("");
			}
			return pk::encode("");
		}

		int check_avaliable(pk::building @building, pk::list<pk::person @> able_person, pk::list<pk::building @> able_spec) // 之所以加入list是为了ai调用时不用重复计算，玩家菜单稍微多点操作问题不大
		{
			if (able_person.count == 0)
				return 1;
			else if (able_spec.count == 0)
				return 2;
			else if (pk::get_district(building.get_district_id()).ap < ACTION_COST)
				return 3;
			else if (pk::get_troops(building) <= TROOP_COST)
				return 4;
			else if (pk::get_food(building) <= FOOD_COST)
				return 5;
			else if (pk::get_gold(building) <= GOLD_COST)
				return 6;
			else if (pk::enemies_around(building))
				return 8;
			// pk::list<pk::person@> able_person = get_able_person(force_);
			else
				return 0;
		}

		string getText()
		{
			return pk::encode("县城管理");
		}

		bool handler()
		{
			if (pk::choose({ pk::encode(" 是 "), pk::encode(" 否 ") }, pk::encode(pk::format("派遣官员管理境内县城。\n(仅可派遣\x1b[18x亲属、功臣\x1b[0x或\x1b[18x属性80\x1b[0x以上\x1b[0x人才)\n消耗主城\x1b[16x{}\x1b[0x:\x1b[0x金\x1b[1x{}\x1b[0x,粮\x1b[1x{}\x1b[0x,兵\x1b[1x{}\x1b[0x", pk::decode(pk::get_name(building_)), GOLD_COST, FOOD_COST, TROOP_COST)), pk::get_person(武将_文官)) == 1)
				return false;

			// pk::list<pk::person@> person_list = get_able_person(force_);//获得可以县城管理的武将数

			// pk::list<pk::city @> city_list = get_able_city(force_); // 获得可以县城管理的武将数
			array<int16> spec_arr = ch::get_base_able_spec_int16(building_, true);

			if (spec_arr.length == 0)
			{
				array<int16> cannot_able_spec_arr = ch::get_force_no_belong_city_able_spec_int16(force_);
				if (cannot_able_spec_arr.length == 0)
					pk::message_box(pk::encode("(哦，没有可用的县城)。"), kunshu_);
				else
				{
					string spen_name = ch::get_spec_name(cannot_able_spec_arr[pk::rand(cannot_able_spec_arr.length - 1)]);
					pk::message_box(pk::encode(pk::format("(\x1b[1x{}\x1b[0x虽然归我军所属，但位属前线，战事频繁，派遣手下也不大合适)", spen_name)), kunshu_);
				}

				return false;
			}
			pk::list<pk::person @> pre_sel_person;
			pre_sel_person.add(able_person_[0]);
			// 县城管理武将选擇
			pk::list<pk::person @> person_sel = pk::person_selector(pk::encode("县城管理武将选择"), pk::encode("选择要县城管理的武将."), able_person_, 1, 1, pre_sel_person, 42);
			if (person_sel.count == 0)
				return false; // 未选擇时取消结束
			@actor = person_sel[0];
			int person_id = person_sel[0].get_id();

			//!!!!看不到封地名，体验不好，或者做成选项？但是封地数量会太多
			// 选擇目标封地
			/*
			pk::list<pk::city @> list_target = pk::city_selector2(pk::encode("选择封地对应城市"), pk::encode("选择封地对应城市."), city_list, 1, 1);
			if (list_target.count == 0)
				return false; // 未选擇时取消结束

			// get_able_building(force_)
			array<int16> spec_arr = get_city_able_spec_int16(list_target[0], force_);*/
			// array<int16> spec_arr = ch::get_force_able_spec_int16(force_,true);

			// pk::info('spec_arr length: ' + (spec_arr.length));
			// int spec_id = choose_spec(spec_arr);
			auto arr = UI::spec_selector(pk::encode("县城选择"), pk::encode("县城选择"), spec_arr, 1, 1);
			if (arr.length == 0)
				return false;
			int spec_id = arr[0];
			return run_order(building_, actor, spec_id, true);
		}

		void scen_县城管理()
		{
			//pk::play_bgm(17);
			pk::message_box(pk::encode(pk::format("\x1b[6x{}\x1b[0x将军,\x1b[16x{}\x1b[0x就交给你管理了.", pk::decode(pk::get_name(actor)), spec_name)), kunshu_);

			switch (pk::rand(3))
			{
				case 0:
					pk::message_box(pk::encode(pk::format("{}一定会把\x1b[16x{}\x1b[0x治理好！", pk::decode(pk::get_msg(pk::msg_param(0, actor, kunshu_))), spec_name)), actor);
					break;
				case 1:
					pk::message_box(pk::encode(pk::format("对{}来说,\x1b[16x{}\x1b[0x治理小事一桩！", pk::decode(pk::get_msg(pk::msg_param(0, actor, kunshu_))), spec_name)), actor);
					break;
				case 2:
					pk::message_box(pk::encode(pk::format("{}定会替主公守住\x1b[16x{}\x1b[0x,不让敌军夺去！", pk::decode(pk::get_msg(pk::msg_param(0, actor, kunshu_))), spec_name)), actor);
					break;
			}

				//pk::cutin(CG_气势);
			spec_name = "";
		}

		// ===================================县城管理开始==============================================
		pk::building @kunshu_building_;
		void init_领地_县城管理(pk::building @building)
		{
			@building_ = @building;
			@loc_building = pk::get_building(pk::get_building_id(building_.pos));

			@force_ = pk::get_force(building.get_force_id());
			if (pk::is_valid_person_id(force_.kunshu))
			{
				@kunshu_ = pk::get_person(force_.kunshu);
				@kunshu_building_ = pk::get_building(kunshu_.service);
			}
			pk::list<pk::person @> able_person_县城管理 = get_able_person(force_);
			check_result_ = check_avaliable_领地_县城管理(loc_building, able_person_县城管理);
		}

		bool isVisible_领地_县城管理()
		{
			if (pk::is_campaign())
				return false;
			int spec_id = ch::to_spec_id(building_.get_id());
			if (!ch::is_valid_spec_id(spec_id))
				return false;
			int force_id = building_.get_force_id();
			if (!pk::is_valid_force_id(force_id))
				return false;
			int spec_person = ch::get_spec_person_id(spec_id);
			if (pk::is_valid_person_id(spec_person))
				return false;
			return true;
		}

		string getText_领地_县城管理()
		{
			return pk::encode("县城管理");
		}

		int check_avaliable_领地_县城管理(pk::building @building, pk::list<pk::person @> able_person)
		{

			if (building is null or !pk::is_alive(building))
				return 5;
			int city_id = pk::get_building_id(building_.get_pos());
			pk::building @location_city = pk::get_building(city_id);

			if (location_city.get_force_id() != building_.get_force_id())
				return 6;
			if (pk::get_district(building.get_district_id()).ap < ACTION_COST)
				return 1;
			else if (pk::get_troops(building) <= TROOP_COST)
				return 2;
			else if (pk::get_food(building) <= FOOD_COST)
				return 3;
			else if (pk::get_gold(building) <= GOLD_COST)
				return 4;
			else if (able_person.count == 0)
				return 7;
			else if (pk::enemies_around(building_))
				return 8;
			else
				return 0;
			// pk::list<pk::person@> able_person = get_able_person(force_);
		}

		bool isEnabled_领地_县城管理()
		{
			if (check_result_ == 0)
				return true;
			return false;
		}

		string getDesc_领地_县城管理()
		{
			switch (check_result_)
			{
				case 1:
					return pk::encode(pk::format("行动力不足 (必须 {} 行动力)", ACTION_COST));
				case 2:
					return pk::encode(pk::format("兵力不足.(主城必须满{} 兵力)", TROOP_COST));
				case 3:
					return pk::encode(pk::format("食物不足.(主城必须满{} 兵粮)", FOOD_COST));
				case 4:
					return pk::encode(pk::format("资金不足 (主城必须满 {} 资金)", GOLD_COST));
				case 5:
					return pk::encode(pk::format("主城异常{}", kunshu_building_.get_id()));
				case 6:
					return pk::encode("据点所在城池非已方势力城池");
				case 7:
					return pk::encode("没有可县城管理的武将. ");
				case 8:
					return pk::encode("附近有敌军不能县城管理. ");
				case 0:
					return pk::encode(pk::format("将领地县城管理给武将. (行动力 {}, 金 {}, 粮 {}, 兵 {})", ACTION_COST, GOLD_COST, FOOD_COST, TROOP_COST));
				default:
					return pk::encode("");
			}
			return pk::encode("");
		}

		bool handler_领地_县城管理()
		{
			if (pk::choose({ pk::encode(" 是 "), pk::encode(" 否 ") }, pk::encode(pk::format("派遣官员管理\x1b[16x{}\x1b[0x。\n(仅可派遣\x1b[18x亲属、功臣\x1b[0x或\x1b[18x属性80\x1b[0x以上\x1b[0x人才)\n消耗主城\x1b[16x{}\x1b[0x:\x1b[0x金\x1b[1x{}\x1b[0x,粮\x1b[1x{}\x1b[0x,兵\x1b[1x{}\x1b[0x", ch::get_spec_name(ch::to_spec_id(building_.get_id())), pk::decode(pk::get_name(loc_building)), GOLD_COST, FOOD_COST, TROOP_COST)), pk::get_person(武将_文官)) == 1)
				return true; // 一级菜单必须选true，false意味着返回上一级菜单，而然一级菜单没有上一级
			able_person_ = get_able_person(force_);
			pk::list<pk::person @> pre_sel_person;
			pre_sel_person.add(able_person_[0]);
			// 县城管理武将选擇
			pk::list<pk::person @> person_sel = pk::person_selector(pk::encode("县城管理武将选择"), pk::encode("选择要县城管理的武将."), able_person_, 1, 1, pre_sel_person, 42);
			if (person_sel.count == 0)
				return true; // 未选擇时取消结束
			@actor = person_sel[0];
			int person_id = person_sel[0].get_id();
			int spec_id = ch::to_spec_id(building_.get_id());
			return run_order(loc_building, actor, spec_id, true);
		}
		// =======================================县城管理结束==========================================

		// ===================================解除县城管理开始==============================================
		int check_result_解除县城管理_;
		void init_领地_解除县城管理(pk::building @building)
		{
			@building_ = @building;
			@force_ = pk::get_force(building.get_force_id());
			if (pk::is_valid_person_id(force_.kunshu))
			{
				@kunshu_ = pk::get_person(force_.kunshu);
				@kunshu_building_ = pk::get_building(kunshu_.service);
			}
			check_result_解除县城管理_ = check_avaliable_领地_解除县城管理(kunshu_building_);
		}

		bool isVisible_领地_解除县城管理()
		{
			if (pk::is_campaign())
				return false;
			int spec_id = ch::to_spec_id(building_.get_id());
			if (!ch::is_valid_spec_id(spec_id))
				return false;
			int force_id = building_.get_force_id();
			if (!pk::is_valid_force_id(force_id) or pk::get_current_turn_force_id() != force_id)
				return false;
			int spec_person = ch::get_spec_person_id(spec_id);
			if (!pk::is_valid_person_id(spec_person))
				return false;
			return true;
		}

		string getText_领地_解除县城管理()
		{
			return pk::encode("解除县城管理");
		}

		int check_avaliable_领地_解除县城管理(pk::building @building)
		{
			if (building is null or !pk::is_alive(building))
				return 2;
			if (pk::get_district(building.get_district_id()).ap < ACTION_COST)
				return 1;
			else
				return 0;
			// pk::list<pk::person@> able_person = get_able_person(force_);
		}

		bool isEnabled_领地_解除县城管理()
		{
			if (check_result_解除县城管理_ == 0)
				return true;
			return false;
		}

		string getDesc_领地_解除县城管理()
		{
			switch (check_result_解除县城管理_)
			{
				case 1:
					return pk::encode(pk::format("行动力不足 (必须 {} 行动力)", ACTION_COST));
				case 0:
					return pk::encode(pk::format("解除该领地的县城管理状态，回收资源. (行动力 {})", ACTION_COST));
				default:
					return pk::encode("");
			}
			return pk::encode("");
		}

		bool handler_领地_解除县城管理()
		{
			if (pk::choose({ pk::encode(" 是 "), pk::encode(" 否 ") }, pk::encode(pk::format("是否解除该领地的县城管理状态。\n(消耗行动力\x1b[1x{}\x1b[0x)", ACTION_COST)), pk::get_person(武将_文官)) == 1)
				return true; // 一级菜单必须选true，false意味着返回上一级菜单，而然一级菜单没有上一级

			pk::list<pk::person @> person_sel;
			int spec_id = ch::to_spec_id(building_.get_id());
			int spec_person = ch::get_spec_person_id(spec_id);
			person_sel.add(pk::get_person(spec_person));

			return run_order_解除县城管理(kunshu_building_, person_sel, true);
		}
		// =======================================解除县城管理结束==========================================
		//========================================玩家支援县城=================================================================//
		array<pk::point_int> get_targets(int max)
		{
			array<pk::point_int> targets;
			auto range = pk::range(src_pos_, max == 0 ? 0 : 1, max);
			for (int i = 0; i < int(range.length); i++)
			{
				auto hex = pk::get_hex(range[i]);
				if (hex.has_building)
				{
					auto building = pk::get_building(range[i]);
					if (building.get_force_id() != src_unit_.get_force_id())
						continue;
					int spec_id = ch::to_spec_id(building.get_id());
					if (ch::is_valid_spec_id(spec_id))
						targets.insertLast(pk::point_int(range[i], 0));
				}
			}
			return targets;
		}

		bool unit_handler(pk::point dst_pos)
		{
			if (调试模式)
				pk::trace("supply spec");
			pk::building @dst_building = pk::get_building(dst_pos);
			int spec_id = ch::to_spec_id(dst_building.get_id());
			auto spec_t = ch::get_spec_p(spec_id);
			string menu_desc = "请决定为" + ch::get_spec_name(spec_id) + "支援" + "的物资数量.";
			int support_limit = pk::min(src_unit_.troops - 1, (src_unit_.food - 1) / 2, 60000 - spec_t.food, 30000 - spec_t.troops);
			menu_desc += "\n(支援最大物资值:\x1b[1x" + support_limit + "\x1b[0x)";
			pk::message_box(pk::encode(menu_desc));

			string numberpad_title = pk::encode("支援数量");
			pk::int_bool numberpad_value = pk::numberpad(numberpad_title, 1, support_limit, 1, cast<pk::numberpad_t @>(function(line, original_value, current_value) { return ""; }));
			/* if (!numberpad_value.second)
			{
				pk::set_pos(src_unit, pos_0);
				if (물자지원_실행부대_행동완료) src_unit.action_done = false;
				src_unit.update();
				return false;
			} */
			if (!numberpad_value.second)
			{
				// if (물자지원_실행부대_행동완료 and pos_0 != src_pos_) src_unit.action_done = true;  //移动了
				if (调试模式)
					pk::trace("has_moved_" + has_moved_);
				if (has_moved_)
					src_unit_.action_done = true;
				return false;
			}

			pk::person @src_leader = pk::get_person(src_unit_.leader);
			int support_amount = numberpad_value.first;
			int get_amout = numberpad_value.first;
			string confirm_desc = "是否确定为" + ch::get_spec_name(spec_id) + "提供\x1b[1x" + support_amount + "兵力\x1b[0x吗?";
			int confirm_value = pk::choose(pk::encode(confirm_desc), { pk::encode("确定"), pk::encode("取消") });

			if (confirm_value == 1)
			{
				if (调试模式)
					pk::trace("has_moved_" + has_moved_);
				if (has_moved_)
					src_unit_.action_done = true;
				return false;
			}

			pk::add_food(src_unit_, -support_amount * 2, true);
			pk::add_troops(src_unit_, -support_amount, true);

			spec_t.add_food(support_amount * 2);
			spec_t.add_troops(support_amount);
			pk::combat_text(support_amount, 1, dst_pos);
			// src_unit_.action_done = true;
			ch::set_unit_action_done(src_unit_);

			return true;
		}
		//================================================支持函数================================================//
		int choose_spec(array<int> spec_arr)
		{
			// 一个城市最多8个？
			//  头5+1 中间4+2 尾部 n+1
			int num = int(spec_arr.length);
			int choose_times = (num - 5) / 4; // 除法直接去掉小数
			int mod = (num - 5) % 4;		  // 取余数做末尾
			// 要获取的是spec_id
			array<string> spec_name_list;
			for (int i = 0; i < pk::min(5, num); ++i)
			{
				spec_name_list.insertLast(pk::encode(get_spec_city_name(spec_arr[i]) + ch::get_spec_name(spec_arr[i])));
			}

			if (num == 6)
				spec_name_list.insertLast(pk::encode(get_spec_city_name(spec_arr[num - 1]) + ch::get_spec_name(spec_arr[num - 1])));
			else if (num > 6)
				spec_name_list.insertLast(pk::encode("下一页"));

			int n = pk::choose(pk::encode("请选择县城."), spec_name_list);
			if (n == 5 and num != 6)
				return choose_spec_mid(spec_arr, 1);
			return spec_arr[n];
		}

		int choose_spec_mid(array<int> spec_arr, int page)
		{
			// 一个城市最多8个？
			//  头5+1 中间4+2 尾部 n+1
			int num = int(spec_arr.length);
			int num2 = (num - 1 - 4 * page);
			if (num2 <= 5)
			{
				// 最后一页
				// 要获取的是spec_id
				array<string> spec_name_list;
				for (int i = (1 + page * 4); i < (1 + page * 4 + num2); ++i)
				{
					spec_name_list.insertLast(pk::encode(get_spec_city_name(spec_arr[i]) + ch::get_spec_name(spec_arr[i])));
				}
				spec_name_list.insertLast(pk::encode("上一页"));
				int n = pk::choose(pk::encode("请选择县城."), spec_name_list);

				if (n == 5 or n == int(spec_name_list.length - 1))
				{
					if (page == 1)
						return choose_spec(spec_arr);
					return choose_spec_mid(spec_arr, page - 1); // 如何返回上一页
				}

				int t = n + (page - 1) * 4 + 5;

				return spec_arr[t];
			}
			else // 不是最后一页
			{
				// 要获取的是spec_id
				array<string> spec_name_list;
				for (int i = (1 + page * 4); i < (1 + page * 4 + 4); ++i)
				{
					spec_name_list.insertLast(pk::encode(get_spec_city_name(spec_arr[i]) + ch::get_spec_name(spec_arr[i])));
				}
				spec_name_list.insertLast(pk::encode("上一页"));
				spec_name_list.insertLast(pk::encode("下一页"));

				int n = pk::choose(pk::encode("请选择县城."), spec_name_list);

				// 非最后一页情况
				if (n == 4)
				{
					if (page != 1)
						return choose_spec_mid(spec_arr, page - 1);
					else
						return choose_spec(spec_arr);
				}
				if (n == 5)
					return choose_spec_mid(spec_arr, page + 1);

				int t = n + (page - 1) * 4 + 5;

				return spec_arr[t];
			}
		}

		string get_spec_city_name(int spec_id)
		{
			pk::point pos0 = ch::get_spec_pos(spec_id);
			int city_id = pk::get_building_id(pos0);
			if (city_id == -1)
				return "";
			return pk::decode(pk::get_name(pk::get_city(city_id)));
		}

		array<int> get_all_spec()
		{
			array<int> temp;
			for (int i = 0; i < ch::get_spec_end(); ++i)
			{
				temp.insertLast(i);
			}
			return temp;
		}

		pk::list<pk::building @> get_city_able_spec_building(pk::building @building)
		{
			pk::list<pk::building @> temp;
			for (int i = 0; i < ch::get_spec_end(); ++i)
			{
				pk::point pos0 = ch::get_spec_pos(i);
				pk::building @building0 = pk::get_building(pos0);

				if (building0 is null)
					continue;
				if (building0.get_force_id() != building.get_force_id())
					continue;
				if (pk::enemies_around(building0))
					continue;
				auto spec_t = ch::get_spec_p(i);
				if (调试模式)
					pk::trace(pk::format("0 {} {}", get_spec_city_name(i), ch::get_spec_name(i)));
				if (spec_t.person != -1)
					continue;
				int city_id = pk::get_building_id(pos0);
				if (调试模式)
					pk::trace(pk::format("1 {} {}", get_spec_city_name(i), ch::get_spec_name(i)));
				if (building.get_id() != city_id)
					continue;
				if (调试模式)
					pk::trace(pk::format("2 {} {}", get_spec_city_name(i), ch::get_spec_name(i)));
				temp.add(building0); // insertLast(i);
			}
			return temp;
		}

		pk::list<pk::city @> get_able_city(pk::force @force)
		{
			pk::list<pk::city @> temp;
			array<int> id_temp;
			for (int i = 0; i < ch::get_spec_end(); ++i)
			{
				pk::point pos0 = ch::get_spec_pos(i);
				auto hex = pk::get_hex(pos0);
				if (!hex.has_building)
					continue;
				pk::building @building0 = pk::get_building(pos0);

				if (building0.get_force_id() != force.get_id())
					continue;
				auto spec_t = ch::get_spec_p(i);
				if (spec_t.person != -1)
					continue;
				int city_id = pk::get_building_id(pos0);
				// if (pk::get_city(city_id).get_force_id() != force.get_id()) continue;
				if (id_temp.find(city_id) < 0 and city_id != -1)
				{
					id_temp.insertLast(city_id);
					temp.add(pk::get_city(city_id));
				}
			}
			return temp;
		}

		pk::list<pk::building @> get_able_building(pk::building @building)
		{
			pk::list<pk::building @> temp;
			for (int j = 0; j < 最大城市县城数; ++j)
			{
				int spec_id = ch::get_base_spec(building.get_id(), j);
				//pk::trace(pk::format("{},spec_id{},封地名：{},", pk::decode(pk::get_name(building)), spec_id,ch::get_spec_name(spec_id)));

				if (ch::is_valid_spec_id(spec_id))
				{
					auto spec_t = ch::get_spec_p(spec_id);
					int person_id = spec_t.person;

					if (spec_t.person == -1 and pk::get_building(ch::to_building_id(spec_id)).get_force_id() == building.get_force_id())
					{
						int building_id = ch::to_building_id(spec_id);
						pk::building @spec = pk::get_building(building_id);
						temp.add(spec);

					}
				}
			}

			return temp;
		}

		pk::list<pk::person @> get_able_person(pk::force @force)
		{
			pk::list<pk::person @> temp;
			pk::list<pk::person @> person_list = pk::get_person_list(force, pk::mibun_flags(身份_都督, 身份_太守, 身份_一般));
			for (int i = 0; i < person_list.count; ++i)
			{
				bool 亲属 = false;
				pk::person @君主 = pk::get_person(force.kunshu);
				if (person_list[i].ketsuen == 君主.ketsuen)
					亲属 = true; /*血缘*/
				else if (pk::is_gikyoudai(person_list[i], 君主.get_id()))
					亲属 = true; /*义兄弟*/
				else if (pk::is_oyako(person_list[i], 君主.get_id()))
					亲属 = true; /*亲子*/
				else if (pk::is_fuufu(person_list[i], 君主.get_id()))
					亲属 = true; /*夫妇*/

				if (person_list[i].stat[武将能力_统率] > 80 or person_list[i].stat[武将能力_武力] > 80 or person_list[i].stat[武将能力_智力] > 80 or person_list[i].stat[武将能力_政治] > 80 or person_list[i].stat[武将能力_魅力] > 80 or person_list[i].kouseki > 10000 or 亲属)
				{

					if (调试模式)
						pk::trace(pk::format("spec_id:{},person_id:{}", ch::get_person_p(person_list[i].get_id()).spec_id, ch::get_person_p(person_list[i].get_id())));
					if (ch::is_valid_spec_id(ch::get_person_p(person_list[i].get_id()).spec_id))
						continue;
					temp.add(person_list[i]);
					if (调试模式)
						pk::trace(pk::format("势力id：{}，武将：{}，统率：{}，spec_id:{}", force.get_id(), pk::decode(pk::get_name(person_list[i])), person_list[i].stat[武将能力_统率], ch::get_person_p(person_list[i].get_id()).spec_id));
				}
			}
			if (temp.count > 1)
			{
				temp.sort(function(a, b) {
					return a.stat[武将能力_统率] + a.stat[武将能力_政治] + (ch::has_skill(a, 特技_治县) ? 50 : 0) > b.stat[武将能力_统率] + b.stat[武将能力_政治] + (ch::has_skill(b, 特技_治县) ? 50 : 0); // 按统率+政治排序
				});
			}
			return temp;
		}

		pk::list<pk::person @> get_base_spec_person(pk::building @building)
		{
			pk::list<pk::person @> temp;
			for (int i = 0; i < ch::get_spec_end(); ++i)
			{
				auto spec_t = ch::get_spec_p(i);
				if (spec_t.person == -1)
					continue;
				pk::point pos0 = ch::get_spec_pos(i);
				int city_id = pk::get_building_id(pos0);
				if (city_id != building.get_id())
					continue;
				temp.add(pk::get_person(spec_t.person));
			}
			return temp;
		}

		pk::point get_enemy_unit_pos(pk::building @building)
		{
			// pk::unit@ dst_unit;
			int range_max = pk::min(10, pk::max(3, 府兵巡防范围));
			auto range = pk::range(building.pos, 1, range_max);

			for (int i = 0; i < int(range.length); i++)
			{
				auto hex = pk::get_hex(range[i]);
				if (hex.has_unit)
				{
					pk::unit @unit = pk::get_unit(range[i]);
					// pk::trace(pk::format("1 unit_id:{}", unit.get_id()));
					if (pk::is_alive(unit) and unit.type_id == 11)
					{
						// pk::trace(pk::format("2 unit_id:{}",unit.get_id()));

						string force_name = pk::decode(pk::get_name(pk::get_force(building.get_force_id())));
					   //pk::trace(pk::format("2 force_name:{}",force_name));
						int building_id = pk::get_building_id(range[i]);
						if (pk::get_building(building_id).get_force_id() != building.get_force_id() and force_name != "贼将")
							continue; // 不属于己方防区的情况 ,贼将可以出来攻击

						if (pk::is_enemy(building, unit))
						{
							// pk::trace(pk::format("3 unit_id:{}", unit.get_id()));
							return unit.pos;
						}
					}
				}
			}
			return pk::point(-1, -1);
		}

		pk::point get_empty_pos(pk::point pos, int distance_min, int distance_max, int weapon_id = -1)
		{
			array<pk::point> range_pos_arr = pk::range(pos, distance_min, distance_max);

			for (int arr_index = 0; arr_index < int(range_pos_arr.length); arr_index++)
			{
				pk::point range_pos = range_pos_arr[arr_index];

				if (!pk::is_valid_pos(range_pos))
					continue;

				pk::hex @hex = pk::get_hex(range_pos);

				int terrain_ide = hex.terrain;
				if (!pk::is_enabled_terrain(terrain_ide))
					continue;

				if (hex.has_building || hex.has_unit)
					continue;

				bool continue_OuterLoop = false;
				// 弩兵需检测周围是否有敌军
				if (weapon_id == 兵器_弩)
				{
					// 如果一格以内有敌人，不生成
					array<pk::point> range_pos_near = pk::range(range_pos, 1, 1);
					for (int arr_index_near = 0; arr_index_near < int(range_pos_near.length); arr_index_near++)
					{
						pk::point range_pos_near0 = range_pos_near[arr_index_near];
						if (!pk::is_valid_pos(range_pos_near0))
							continue;
						pk::hex @hex_near = pk::get_hex(range_pos_near0);
						if (hex_near.has_unit)
						{
							pk::unit @dst = pk::get_unit(range_pos_near0);
							if (dst is null)
								continue;

							if (pk::is_enemy(dst, pk::get_building(pos)))
							{
								continue_OuterLoop == true;
								break;
							}
						}
					}
				}

				if (!continue_OuterLoop)
				{
					int terrain_id = hex.terrain;
					if (!pk::is_valid_terrain_id(terrain_id))
						continue;
					if (!pk::is_enabled_terrain(terrain_id))
						continue;
					return range_pos;
				}
			}
			return pk::point(-1, -1);
		}

		//-----------------------府兵部队队生成相关-------------------------------------//
		// 基本事件_府兵部队_生成
		void func_府兵部队_生成(pk::building @building, pk::person @src_person, pk::point dst_pos, int spec_id, int troops, int gold, int food, int num)
		{
			pk::point unit_pos = get_empty_pos(building.pos, 1, 2);
			if (!pk::is_valid_pos(unit_pos))
				return;
			if (!pk::is_in_screen(dst_pos))
			{
				auto hex = pk::get_hex(dst_pos);
				if (hex.has_unit)
				{
					pk::unit @unit0 = pk::get_unit(dst_pos);
					//有了府兵难度控制之后,这个随机好像不是很有必要? 待风神确定
					// if (!unit0.is_player())
					// {
					// 	int chance = pk::rand(100);
					// 	if (chance > 90)
					// 		num = pk::max(0, num - 3);
					// 	else if (chance > 20)
					// 		num = pk::max(0, num - 2);
					// 	else
					// 		num = pk::max(0, num - 1);
					// }
				}
			}

			for (int count = 0; count < num; count++)
			{
				if (!func_person_slot_available())
					break; // 沒有空余武将位则不生成
				if (count != 0)
					dst_pos = get_enemy_unit_pos(building);
				if (dst_pos.x == -1)
					break;

				pk::person @f_person = func_create_person(src_person, building);
				if(f_person is null) return;
				// 获取f_person的ID
				int f_person_id = f_person.get_id();

				if (!pk::is_alive(f_person))
				{
					pk::reset(f_person);
					continue;
				}
				bool has_熟练兵 = pk::has_tech(building, 技巧_熟练兵);
				int src_troops = get_best_troops(troops, num - count, has_熟练兵);
				if (troops < 3000 and troops > 1000)
					src_troops = troops;
				if (src_troops < 1000)
				{
					pk::reset(f_person);
					break;
				}					  // 尝试修改为小于1000不再出兵
				troops -= src_troops; // 已出征过一次的兵需要休息，不再再次出征
				int ground_wpn = get_best_ground_wpn(f_person, troops);
				if (ground_wpn == 兵器_弩 or !pk::is_valid_pos(unit_pos))
					unit_pos = get_empty_pos(building.pos, 1, 2); // 生成部队前再次核实坐标有效
				pk::unit @src_unit = func_create_unit(building, f_person, unit_pos, spec_id, num /*统领数*/, src_troops, ground_wpn, gold, food);
				//pk::trace("src_unit force" + src_unit.get_force_id() + ",f_person: force:" + f_person.get_id() + f_person.get_force_id());
				if (!pk::is_alive(src_unit))
				{
					pk::kill(src_unit);
					pk::reset(f_person);
					continue;
				}


				if (int(pk::get_movable_pos(src_unit).length) == 0)
				{
					kill(src_unit, spec_id);
					pk::reset(f_person);
					break;
				}

				if (pk::get_hex(src_unit.pos).terrain == 地形_崖)
					pk::core::add_hidden_skill(f_person.get_id(), 特技_山战);
				else
					pk::core::add_hidden_skill(f_person.get_id(), 特技_拱戍);

				pk::core::add_hidden_skill(f_person.get_id(), 特技_幸运, 1);

				pk::set_order(src_unit, 部队任务_攻击, dst_pos);
				pk::run_order(src_unit);
				// if (!pk::run_order(src_unit)) { kill(src_unit, spec_id); pk::reset(f_person); continue; }
				if (pk::is_alive(src_unit)) // 每一步需检测部队是否还活着
				{
					src_unit.action_done = false;
					if ((pk::get_max_hp(building) - building.hp) > 0)
					{
						pk::set_order(src_unit, 部队任务_修复, building.pos, building.get_id());
						pk::run_order(src_unit);
					}
					else
					{
						// 无需修复的情况

						if (!pk::is_neighbor_pos(src_unit.pos, building.pos)) // 如果部队就在建筑旁，无需移动
						{
							pk::point next_pos = get_empty_pos(building.pos, 1, 1);
							if (next_pos.x != -1 and next_pos != src_unit.pos)
							{
								// pk::trace("unit_id:" + src_unit.get_id() + "src_pos x" + src_unit.pos.x + "y:" + src_unit.pos.y + ",next_pos: x:" + next_pos.x + "y:" + next_pos.y);
								auto paths = pk::get_path(src_unit, src_unit.pos, next_pos);
								if (paths.length != 0)
									pk::move(src_unit, paths);
							}
						}
						// pk::set_order(src_unit, 部队任务_移动, next_pos);//直接执行移动任务部队还是可能会攻击
					}

					if (pk::is_alive(src_unit)) // 每一步需检测部队是否还活着
					{
						if (pk::is_in_screen(src_unit.get_pos()))
						{
							switch (pk::rand(3))
							{
								case 0:
									pk::say(pk::encode("任务完成, 回去吧!"), pk::get_person(src_unit.leader));
									break;
								case 1:
									pk::say(pk::encode("兄弟们, 回家吧!"), pk::get_person(src_unit.leader));
									break;
								case 2:
									pk::say(pk::encode("干的不错，回去大人必有赏赐!"), pk::get_person(src_unit.leader));
									break;
							}
						}

						kill(src_unit, spec_id);
					}
				}
				if (f_person !is null)
					pk::core::remove_all_hidden_skill(f_person.get_id());
				pk::reset(f_person);
			}
		}

		void kill(pk::unit @unit, int spec_id)
		{
			auto spec_t = ch::get_spec_p(spec_id);
			spec_t.add_troops(unit.troops);
			spec_t.add_gold(unit.gold);
			spec_t.add_food(unit.food);
			pk::kill(unit, true);
		}

		// 遍历所有武将，身??死亡或无的都可用来生成
		bool func_person_slot_available()
		{
			for (int person_id = 敌将_开始; person_id < 敌将_末; person_id++)
			{
				pk::person @person = pk::get_person(person_id);
				if (person.mibun == 身份_无)
					return true;
				if (person.mibun == 身份_死亡)
					return true;
			}
			return false;
		}

		// 统领武将生成
		pk::person @func_create_person(pk::person @person, pk::building @building)
		{
			pk::person @f_person = ch::create_temp_person(武将_卫士, 17);//模板武将其实无所谓，因为后续还会设置
			//pk::trace("func_create_person:" + f_person.get_id());
			ch::set_spec_temp_person(f_person, person, person.get_district_id());
			//pk::person @f_person = pk::create_bandit(pk::get_person(武将_卫士));
			//pk::trace("f_person.get_id()" + f_person.get_id());
			return f_person;
		}

		// 府兵部队生成-改
		pk::unit @func_create_unit(pk::building @src_base, pk::person @f_person, pk::point unit_pos, int spec_id, int num /*统领数*/, int troops, int ground_wpn, int gold, int food)
		{

			// int ground_wpn = get_best_ground_wpn(f_person, troops); // 陆上兵器
			int sea_wpn = 兵器_走舸; // 水上兵器
			int src_troops = troops;
			int src_gold = int(gold / num);
			int src_food = int(food / num);


			pk::unit @src_unit = pk::create_unit(src_base, f_person, null, null, src_troops, ground_wpn, sea_wpn, src_gold, src_food, unit_pos);
			//pk::trace(pk::format("{},{}", src_troops, src_unit.troops));
			src_unit.energy = 120;

			if (pk::is_alive(src_unit))
			{
				auto spec_t = ch::get_spec_p(spec_id);
				spec_t.add_troops(-src_unit.troops);
				spec_t.add_gold(-src_unit.gold);
				spec_t.add_food(-src_unit.food);
				pk::set_troops(src_unit, src_troops);
				//pk::trace(pk::format("{},{}", src_troops, src_unit.troops));
			}

			return src_unit;
		}

		int get_best_ground_wpn(pk::person @person, int troops)
		{
			/*
			const int 兵器_枪 = 1;
			const int 兵器_戟 = 2;
			const int 兵器_弩 = 3;
	c			onst int 兵器_战马 = 4;
				 */
			int best_weapon = -1;
			int best_heishu = -1;
			for (int weapon_id = 1; weapon_id < 4; weapon_id++)
			{

				if (person.tekisei[weapon_id - 1] > best_heishu)
				{
					best_heishu = person.tekisei[weapon_id - 1];
					best_weapon = weapon_id;
				}
				// pk::trace(pk::format("weapon id :{}", weapon_id));
			}
			if (person.base_stat[武将能力_武力] + person.base_stat[武将能力_统率] < 120 or troops < 3000)
				best_weapon = 兵器_弩;

			// pk::trace("适性" + person.tekisei[兵种_弩兵]);
			return best_weapon;
		}

		int get_best_troops(int base_troops, int num, bool has_tech)
		{
			int i = num;
			do
			{
				if (base_troops / i >= 3000)
				{
					if (调试模式)
						pk::trace(pk::format("{},{},{}", i, base_troops / i, base_troops));
#if param_set
					return pk::min(5000 + (has_tech ? pk::get_tech_param().gunsei_inc : 0), base_troops / i); // 最多8000,最少3000
#endif
#if not_param_set
					return pk::min(5000 + (has_tech ? int(pk::core["military_reform"]) : 0), base_troops / i); // 最多8000,最少3000
#endif
				}
				i -= 1;
			} while (i >= 1);
			return base_troops;
		}

		/// 范围随机值 :
		int func_数组_范围_随机值(array<int> int_value_arr)
		{
			pk::random random(pk::rand());
			return random(int_value_arr[0], int_value_arr[1]);
		}
	} Main main;
}